import { FarrisDesignBaseNestedComponent } from '@farris/designer-element';
import { DesignerEnvType, FormBasicService, WebCmdService } from '@farris/designer-services';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { cloneDeep } from 'lodash-es';
import Sortable from 'sortablejs';
// import { NocodeToolBarProp } from '../property/nocode-property-config';
import { ToolBarProp } from '../property/property-config';
import { ToolBarSchema, ToolBarType } from '../schema/schema';
import { default as FdToolBarItemComponent, default as ToolBarItemComponent } from './toolbaritem/component/fd-toolbar-item';
import { ToolBarItemSchema, ToolBarItemType } from './toolbaritem/schema/schema';

export default class FdToolBarComponent extends FarrisDesignBaseNestedComponent {

    envType: DesignerEnvType;

    /** 元数据（DOM结构） */
    component: ToolBarType;

    /** 工具栏按钮组件实例 */
    toolBarItem: ToolBarItemComponent;

    /** 工具栏按钮组件实例列表 */
    toolBarItemList: ToolBarItemComponent[];

    /** 工具栏按钮元数据 */
    items: Array<ToolBarItemType>;

    /** 当前选中的按钮id，用于在工具栏attach方法中触发选中某一个按钮 */
    selectedId: string;

    selected: ToolBarItemComponent;

    /** 当前选中的按钮实例 */
    selectedToolbarItem: ToolBarItemComponent;

    /** 按钮对齐方式，默认为flex-end。在section toolbar的场景下值为false */
    justifyContentEnd = true;

    isDraggable = false;

    /** 设计器中二级按钮的展示位置：向下bottom / 向上top。目前只有ModalFooter中toolbar的展示位置为向上 */
    popDirection: string;

    constructor(component: any, options: any) {
        super(component, options);

        this.popDirection = this.options['popDirection'] || 'bottom';
        const serviceHost = this.options.designerHost;
        const formBasicService = serviceHost.getService('FormBasicService') as FormBasicService;
        if (formBasicService) {
            this.envType = formBasicService.envType;
        }

        // 增加操作按钮
        if (this.envType !== DesignerEnvType.noCode) {
            this.customToolbarConfigs = [
                {
                    id: 'appendItem',
                    title: '新增按钮',
                    icon: 'f-icon f-icon-plus-circle text-white',
                    click: (e) => {
                        e.stopPropagation();
                        this.appendItem(ToolBarItemSchema);
                    }
                }
            ];
        }
        this.initItems();

    }


    init() {
        this.components = [];
        const options = Object.assign({}, this.options, { childComponents: [], parent: this });
        this.toolBarItemList = this.items.map(item => {
            return new ToolBarItemComponent(item, options, {
                isChildOfToolBar: true,
                viewModelId: this.viewModelId,
                componentId: this.componentId
            });

        });
        this.components = this.components.concat(this.toolBarItemList);

        if (this.selectedId) {
            this.selected = this.toolBarItemList.find(item => item.id === this.selectedId);
        }
    }

    initItems() {
        this.items = this.component.items;
    }
    /**
     * 不支持删除
     */
    checkCanDeleteComponent(): boolean {
        return false;
    }
    /**
     * 不允许移动
     */
    checkCanMoveComponent(): boolean {
        return false;
    }
    /**
     * 隐藏间距
     */
    hideNestedPaddingInDesginerView(): boolean {
        return true;
    }
    getDefaultSchema(): any {

        return cloneDeep(ToolBarSchema);
    }

    render(): any {
        return super.render(this.renderTemplate(this.type, {
            component: this.component,
            toolBarItemList: this.toolBarItemList,
            justifyContentEnd: this.justifyContentEnd
        }));
    }

    /**
     * 元素扩展事件
     */
    attach(element: HTMLElement): Promise<any> {
        const superAttach = super.attach(element);
        this.toolBarItemList.forEach((toolBarItem, index) => {
            const itemId = toolBarItem.component.id;
            this.loadRefs(element, {
                [itemId]: 'm'
            });
            toolBarItem.attach(this.refs[itemId][0]);
        });
        this.registerDnd();


        return superAttach;
    }


    registerDnd() {
        // 加载子组件
        const dragToolBarContainer = this.element.querySelector('.toolbar-drag');
        if (dragToolBarContainer) {
            // tslint:disable-next-line:no-unused-expression
            new Sortable(dragToolBarContainer, {
                direction: 'horizontal',
                animation: 150,
                dragClass: '',
                delay: 50, // 鼠标按下后多久才允许拖动,如果不设置该属性虽然可以执行点击事件，但是该元素会被轻微的被拖动一下，用户体验非常不好
                forceFallback: true,
                fallbackClass: 'sortable-mirror', // 为镜像元素增加样式
                onChoose: (e) => {
                },
                onStart: (e) => {
                    this.isDraggable = true;
                },
                onMove: (e) => {
                    // 为工具栏增加样式，用于控制拖拽过程中按钮操作栏的样式
                    dragToolBarContainer.classList.add('sortable-toolbar-container');

                    this.isDraggable = true;
                },
                onClone: (e) => {
                },
                onEnd: (evt) => {
                    if (!this.isDraggable) {
                        return;
                    }

                    dragToolBarContainer.classList.remove('sortable-toolbar-container');

                    // 需要重新计算选中按钮工具栏的位置
                    const selectedButtonDiv = dragToolBarContainer.querySelector('.dgComponentSelected') as HTMLElement;
                    if (this.selectedToolbarItem && selectedButtonDiv && selectedButtonDiv.children && selectedButtonDiv.children.length >= 2) {
                        const buttonEle = selectedButtonDiv.children[1] as HTMLElement;
                        this.selectedToolbarItem.setPositionOfToolbarIcon(buttonEle);

                    }
                    // 调整左右位置
                    this.dragEnd(evt);
                    this.isDraggable = false;
                }
            });
        }
    }

    /**
     * 拖拽结束事件
     */
    dragEnd(e: any) {
        const oldIndex = e.oldIndex;
        const newIndex = e.newIndex;

        if (oldIndex !== newIndex) {
            // 修改DOM中按钮的顺序
            const item = this.items[oldIndex];
            this.items.splice(oldIndex, 1);
            this.items.splice(newIndex, 0, item);

            // 修改按钮实例的顺序
            const itemCmp = this.toolBarItemList[oldIndex];
            this.toolBarItemList.splice(oldIndex, 1);
            this.toolBarItemList.splice(newIndex, 0, itemCmp);
        }

    }



    public appendItem(item) {
        if (!this.items) {
            return;
        }
        const itemSchema = Object.assign({}, cloneDeep(item));
        itemSchema.id = `${itemSchema.id}-${Math.random().toString(36).slice(2, 6)}`;
        this.items.push(itemSchema);

        this.setSelectedId(itemSchema.id);
        this.rebuild();
    }

    /**
     * 父元素调用删除
     * @param id
     */
    public removeToolBarItem(id: string) {
        const items = this.items;
        // 删除元数据
        const itemToRemove = items.find(item => item.id === id);
        const mesService = this.options.designerHost.getService('MessagerService');
        mesService.question(`确定删除按钮【${itemToRemove['title'] || itemToRemove.text}】？`, () => {
            this.confirmRemoveToolbarItem(id);
        });
    }

    confirmRemoveToolbarItem(id: string) {
        const items = this.items;
        // 删除元数据
        const itemToRemoveIndex = items.findIndex(item => item.id === id);
        if (itemToRemoveIndex > -1) {
            this.selectedToolbarItem = null;
            items.splice(itemToRemoveIndex, 1);

            // 自动选中下一个按钮
            const nextBtnId = items[itemToRemoveIndex] && items[itemToRemoveIndex].id;
            this.setSelectedId(nextBtnId);


            // 删除二级按钮
            if (this instanceof FdToolBarItemComponent) {
                if (!nextBtnId) {
                    this.parent.emit('clearPropertyPanel');
                }
                this.parent.rebuild();

                this.syncActions();

            } else {
                // 删除一级按钮
                if (!nextBtnId) {
                    this.emit('clearPropertyPanel');
                }
                this.rebuild();

                this.syncActions();
            }
        }
    }
    /**
     * 复制按钮
     * @param id 
     */
    public cloneToolBarItem(id: string) {
        const itemToClone = this.items.find(item => item.id === id);
        if (!itemToClone) {
            return;
        }
        const itemToCloneIndex = this.items.findIndex(item => item.id === id);
        // 点击事件不复制
        const clonedToolBarItem = Object.assign(cloneDeep(itemToClone),
            {
                id: `${this.type}-cloned-${Math.random().toString(36).slice(2, 6)}`,
                click: null
            });

        let itemsToClone = [];
        if (clonedToolBarItem.items && clonedToolBarItem.items.length) {
            itemsToClone = clonedToolBarItem.items.map(i => Object.assign(cloneDeep(i),
                {
                    id: `${this.type}-cloned-${Math.random().toString(36).slice(2, 6)}`,
                    click: null
                }));
        }
        clonedToolBarItem.items = itemsToClone;

        // 添加到被复制元素的后面
        this.items.splice(itemToCloneIndex + 1, 0, clonedToolBarItem);

        this.setSelectedId(clonedToolBarItem.id);

        this.rebuild();
    }

    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options && this.options.designerHost;

        // if (this.envType === DesignerEnvType.noCode) {
        //     const prop: NocodeToolBarProp = new NocodeToolBarProp(serviceHost, this.viewModelId, this.componentId);
        //     const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        //     return propertyConfig;
        // } else {
        const prop: ToolBarProp = new ToolBarProp(serviceHost, this.viewModelId, this.componentId);
        const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        return propertyConfig;
        // }

    }

    /**
     * 属性变更后事件：默认监听样式类属性变更，并触发模板重绘
     * @param changeObject 变更集
     * @param propertyIDs 需要额外监听的属性ID列表
     */
    onPropertyChanged(changeObject: any): void {
        if (['text', 'icon', 'disable', 'class'].includes(changeObject.propertyID)) {
            // 重新组装子元素实例  便于拖拽后未保存的场景
            // if (this instanceof FdToolBarComponent) {
            //     this.init();
            // }
            this.triggerRedraw();
        }
        if (['items'].includes(changeObject.propertyID)) {
            this.parent.redraw();
        }
    }


    setSelectedId(id: string) {
        this.selectedId = id;
    }

    /**
     * 选中工具栏后：关闭二级按钮的下拉面板
     * @param e 点击事件
     */
    afterComponentClicked(e?: PointerEvent): void {
        const panelLists = this.element.querySelectorAll('[ref="dropdown-button"]+div');
        if (panelLists && panelLists.length) {
            panelLists.forEach(otherList => {
                otherList.classList.remove('d-block');
                otherList.classList.add('d-none');
            });

        }
    }

    /**
     * 涉及到按钮绑定事件的删除，故触发同步actions操作
     */
    syncActions() {
        const webCmdService = this.options.designerHost.getService('WebCmdService') as WebCmdService;
        webCmdService.syncActions();
    }
}
